#include"mstdio.h"


mFILE *mfopen(const char *pathname, const char *mode)
{
    int fd=-1;
    // 根据打开模式选择不同的文件打开方式 
    if(strcmp(mode,"w")==0)  // 写入模式：创建/截断文件 
    {
        fd=open(pathname,O_WRONLY | O_CREAT | O_TRUNC, 0666);
    }
    else if(strcmp(mode,"r")==0)  // 只读模式 
    {
        fd=open(pathname,O_RDONLY);
    }
    else if(strcmp(mode,"a")==0)  // 追加模式 
    {
        fd=open(pathname,O_WRONLY | O_CREAT | O_APPEND, 0666);
    }
    // 检查文件是否成功打开 
    if(fd<0)
    {
        return NULL;
    }

    // 分配mFILE结构体内存 
    mFILE* mf=malloc(sizeof(mFILE));
    // 内存分配失败处理 
    if(!mf)
    {
        close(fd);
        return NULL;
    }

    // 初始化结构体字段 
    mf->flag=FLUSH_LINE;     // 默认行缓冲模式 
    mf->fileno=fd;           // 设置文件描述符 
    mf->size=0;              // 初始化缓冲区大小为0 
    mf->cap=SIZE;            // 设置缓冲区容量 

    return mf;
}



int mfflush(mFILE *_stream)
{
    // 检查缓冲区是否有数据需要刷新 
    if(_stream->size>0)
    {
        // 将缓冲区数据写入文件 
        write(_stream->fileno,_stream->outbuffer,_stream->size);
        _stream->size=0;  // 重置缓冲区大小 
    }
    return 0;  // 总是返回成功 
}

size_t mfwrite(const void *ptr,int size, mFILE *stream)
{
    // 将数据拷贝到缓冲区 
    memcpy(stream->outbuffer+stream->size,ptr,size);
    stream->size+=size; // 更新缓冲区当前大小 
    // 根据刷新模式决定是否立即刷新 

    if(stream->flag==FLUSH_LINE && stream->size>0&&stream->outbuffer[stream->size-1]=='\n')  // 行缓冲且遇到换行符 
    {
        mfflush(stream);
    }
    else if(stream->flag==FLUSH_FULL&&stream->size>=stream->cap)  // 全缓冲且缓冲区满 
    {
        mfflush(stream);
    }

    return size;  // 返回成功写入的字节数
}


int mfclose(mFILE *stream) 
{
    if (stream == NULL) 
    {
        return -1;  // 错误：传入空指针
    }

    // 1. 刷新缓冲区（如果还有未写入的数据）
    if (stream->size > 0) 
    {
        mfflush(stream);
    }

    // 2. 关闭文件描述符
    int ret = close(stream->fileno);
    if (ret < 0) 
    {
        // 关闭失败，但仍然需要释放内存
        free(stream);
        return -1;
    }

    // 3. 释放 mFILE 结构体
    free(stream);

    return 0;  // 成功
}


int main()
{
    mFILE *mf = mfopen("test.txt", "w");
    if (!mf) {
        perror("mfopen failed");  // 打印错误信息
        return 1;
    }
    size_t written = mfwrite("Hello", 5, mf);  // written = 5
    mfclose(mf);
    return 0;
}